package com.dimenlink.service.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import com.dimenlink.entity.constants.Constants;
import com.dimenlink.entity.enums.ResponseCodeEnum;
import com.dimenlink.entity.enums.UserActionTypeEnum;
import com.dimenlink.entity.po.UserInfo;
import com.dimenlink.entity.po.VideoComment;
import com.dimenlink.entity.po.VideoInfo;
import com.dimenlink.entity.query.*;
import com.dimenlink.exception.BusinessException;
import com.dimenlink.mappers.UserInfoMapper;
import com.dimenlink.mappers.VideoCommentMapper;
import com.dimenlink.mappers.VideoInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.dimenlink.entity.enums.PageSize;
import com.dimenlink.entity.po.UserAction;
import com.dimenlink.entity.vo.PaginationResultVO;
import com.dimenlink.mappers.UserActionMapper;
import com.dimenlink.service.UserActionService;
import com.dimenlink.utils.StringTools;
import org.springframework.transaction.annotation.Transactional;


/**
 * 用户行为 点赞、评论 业务接口实现
 */
@Service("userActionService")
public class UserActionServiceImpl implements UserActionService {

	@Resource
	private UserActionMapper<UserAction, UserActionQuery> userActionMapper;

	@Resource
	private VideoInfoMapper<VideoInfo, VideoInfoQuery> videoInfoMapper;
    @Resource
    private UserInfoMapper<UserInfo, UserInfoQuery> userInfoMapper;

	@Resource
	private VideoCommentMapper<VideoComment, VideoCommentQuery> videoCommentMapper;

	/**
	 * 根据条件查询列表
	 */
	@Override
	public List<UserAction> findListByParam(UserActionQuery param) {
		return this.userActionMapper.selectList(param);
	}

	/**
	 * 根据条件查询列表
	 */
	@Override
	public Integer findCountByParam(UserActionQuery param) {
		return this.userActionMapper.selectCount(param);
	}

	/**
	 * 分页查询方法
	 */
	@Override
	public PaginationResultVO<UserAction> findListByPage(UserActionQuery param) {
		int count = this.findCountByParam(param);
		int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

		SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
		param.setSimplePage(page);
		List<UserAction> list = this.findListByParam(param);
		PaginationResultVO<UserAction> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
		return result;
	}

	/**
	 * 新增
	 */
	@Override
	public Integer add(UserAction bean) {
		return this.userActionMapper.insert(bean);
	}

	/**
	 * 批量新增
	 */
	@Override
	public Integer addBatch(List<UserAction> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.userActionMapper.insertBatch(listBean);
	}

	/**
	 * 批量新增或者修改
	 */
	@Override
	public Integer addOrUpdateBatch(List<UserAction> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.userActionMapper.insertOrUpdateBatch(listBean);
	}

	/**
	 * 多条件更新
	 */
	@Override
	public Integer updateByParam(UserAction bean, UserActionQuery param) {
		StringTools.checkParam(param);
		return this.userActionMapper.updateByParam(bean, param);
	}

	/**
	 * 多条件删除
	 */
	@Override
	public Integer deleteByParam(UserActionQuery param) {
		StringTools.checkParam(param);
		return this.userActionMapper.deleteByParam(param);
	}

	/**
	 * 根据ActionId获取对象
	 */
	@Override
	public UserAction getUserActionByActionId(Integer actionId) {
		return this.userActionMapper.selectByActionId(actionId);
	}

	/**
	 * 根据ActionId修改
	 */
	@Override
	public Integer updateUserActionByActionId(UserAction bean, Integer actionId) {
		return this.userActionMapper.updateByActionId(bean, actionId);
	}

	/**
	 * 根据ActionId删除
	 */
	@Override
	public Integer deleteUserActionByActionId(Integer actionId) {
		return this.userActionMapper.deleteByActionId(actionId);
	}

	/**
	 * 根据VideoIdAndCommentIdAndActionTypeAndUserId获取对象
	 */
	@Override
	public UserAction getUserActionByVideoIdAndCommentIdAndActionTypeAndUserId(String videoId, Integer commentId, Integer actionType, String userId) {
		return this.userActionMapper.selectByVideoIdAndCommentIdAndActionTypeAndUserId(videoId, commentId, actionType, userId);
	}

	/**
	 * 根据VideoIdAndCommentIdAndActionTypeAndUserId修改
	 */
	@Override
	public Integer updateUserActionByVideoIdAndCommentIdAndActionTypeAndUserId(UserAction bean, String videoId, Integer commentId, Integer actionType, String userId) {
		return this.userActionMapper.updateByVideoIdAndCommentIdAndActionTypeAndUserId(bean, videoId, commentId, actionType, userId);
	}

	/**
	 * 根据VideoIdAndCommentIdAndActionTypeAndUserId删除
	 */
	@Override
	public Integer deleteUserActionByVideoIdAndCommentIdAndActionTypeAndUserId(String videoId, Integer commentId, Integer actionType, String userId) {
		return this.userActionMapper.deleteByVideoIdAndCommentIdAndActionTypeAndUserId(videoId, commentId, actionType, userId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveAction(UserAction bean) {

		// 查询视频信息
		VideoInfo videoInfo = videoInfoMapper.selectByVideoId(bean.getVideoId());
		if (videoInfo == null) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}
		bean.setVideoUserId(videoInfo.getUserId());

		// 判断行为类型
		UserActionTypeEnum actionTypeEnum = UserActionTypeEnum.getByType(bean.getActionType());
		// 行为类型不存在
		if (actionTypeEnum == null) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}

		// 查询行为
		UserAction dbAction = userActionMapper.selectByVideoIdAndCommentIdAndActionTypeAndUserId(bean.getVideoId(),
				bean.getCommentId(), bean.getActionType(),bean.getUserId());
		bean.setActionTime(new Date());

		switch (actionTypeEnum) {
			case VIDEO_LIKE:
			case VIDEO_COLLECT:
				if (dbAction != null) {
					userActionMapper.deleteByActionId(dbAction.getActionId());
				} else {
					userActionMapper.insert(bean);
				}
				Integer changeCount = dbAction == null? Constants.ONE : -Constants.ONE;
				videoInfoMapper.updateCountInfo(bean.getVideoId(), actionTypeEnum.getField(), changeCount);
				if (actionTypeEnum == UserActionTypeEnum.VIDEO_COLLECT.VIDEO_LIKE) {
					// TODO 更新es的收藏数量
				}
				break;
			case VIDEO_COIN:
				if(videoInfo.getUserId().equals(bean.getUserId())){
					throw new BusinessException("up主不可以给自己投币哦");
				}
				if (dbAction != null){
					throw new BusinessException("你已经投过币了，up主在线感谢");
				}
				//减去用户硬币
				Integer updateCount = userInfoMapper.updateCoinCountInfo(bean.getUserId(), -bean.getActionCount());
				if (updateCount == 0) {
					throw new BusinessException("硬币不够了");
				}
				//给up主加硬币
				updateCount = userInfoMapper.updateCoinCountInfo(videoInfo.getUserId(), bean.getActionCount());
				if (updateCount == 0) {
					throw new BusinessException("投币失败");
				}
				userActionMapper.insert(bean);
				//更新视频操作数
				videoInfoMapper.updateCountInfo(bean.getVideoId(), actionTypeEnum.getField(), bean.getActionCount());
				break;
			case COMMENT_LIKE:
			case COMMENT_HATE:
				// 如果当前行为类型是 COMMENT_LIKE（评论点赞），则对立行为类型为 COMMENT_HATE（评论点踩）,否则，对立行为类型为 COMMENT_LIKE（评论点赞）。
				UserActionTypeEnum opposeTypeEnum = UserActionTypeEnum
						.COMMENT_LIKE == actionTypeEnum ? UserActionTypeEnum.COMMENT_HATE : UserActionTypeEnum.COMMENT_LIKE;
				// 获取对立行为
				UserAction opposeAction = userActionMapper.selectByVideoIdAndCommentIdAndActionTypeAndUserId(bean.getVideoId(), bean.getCommentId(),
						opposeTypeEnum.getType(), bean.getUserId());

				// 删除对立行为
				if (opposeAction != null) {
					userActionMapper.deleteByActionId(opposeAction.getActionId());
				}

				// 插入当前行为
				if (dbAction != null) {
					userActionMapper.deleteByActionId(dbAction.getActionId());
				} else {
					userActionMapper.insert(bean);
				}

				// 更新评论操作数
				changeCount = dbAction == null ? Constants.ONE : -Constants.ONE;
				Integer opposeChangeCount = -changeCount;
				videoCommentMapper.updateCountInfo(bean.getCommentId(), actionTypeEnum.getField(), changeCount, opposeAction == null ? null : opposeTypeEnum.getField(),
						opposeChangeCount);
				break;
		}
	}
}